<template>
  <section
    id="appMaker"
    ref="appMaker"
    class="apps-maker"
    :class="{'is-footer': _footer}"
    :style="styleInfo()"
    @scroll="handleScroll"
  >
    <!--    <section class="apps-maker-body-banner">-->
    <!--      <div>-->
    <!--        <p class="close-banner" @click="close" />-->
    <!--      </div>-->
    <!--    </section>-->
    <section ref="myHeader" class="apps-maker-header">
      <v-header v-if="_header" :is-init-data="isInitData" :var-info="varInfo" :option="headerconfig" />
    </section>

    <section class="apps-maker-body" :style="{paddingBottom : _paddingBottom}">
      <section ref="setTop" style="margin-top: 0" />
      <section v-for="(widgets, index) in map" :key="index">
        <section
          v-for="widget in widgets"
          :id="widget.id"
          :key="widget.key"
          class="widget-item"
          :class="{'hide': hideList.includes(widget.id)}"
        >
          <component
            :is="widget.type"
            ref="widget"
            :relation="relation"
            :var-info="varInfo"
            :option="widget.option"
            :is-init-data="isInitData"
          />
        </section>
      </section>
    </section>

    <section class="apps-maker-footer">
      <v-footer v-if="_footer" :is-init-data="isInitData" :option="footerconfig" />
    </section>
  </section>
</template>
<script>
import FieldMap from '@/components/CustomPage/apps/map'
import { randomString } from '@/utils'
import VFooter from '@/components/CustomPage/apps/widget/footer'
import VHeader from '@/components/CustomPage/apps/widget/header'
import Queue from '@/utils/queue'

export default {
  name: 'AppsMaker',
  components: { VHeader, VFooter },
  props: {
    option: {
      type: Object,
      default: {}
    },
    varInfo: {
      type: Object,
      default: () => {
      }
    },
    isInitData: {
      type: Boolean,
      default: false
    }
  },
  provide() {
    return {
      footerHeight: () => this._footerHeight,
      headerHeight: () => this._headerHeight
    }
  },
  data() {
    return {
      values: {},
      keyMap: {},
      map: [],
      queue: null,
      hideList: []
    }
  },
  computed: {
    components() {
      return this.option.components
    },
    relation() {
      return this.option.relation
    },
    pageconfig() {
      return this.option.pageconfig
    },
    headerconfig() {
      return this.option.headerconfig
    },
    footerconfig() {
      return this.option.footerconfig
    },
    pagecolor() {
      return this.pageconfig.pagecolor || '$fff'
    },
    pageimage() {
      return this.pageconfig.pageimage || ''
    },
    _footer() {
      return this.pageconfig.footer
    },
    _header() {
      return this.pageconfig.header
    },
    _paddingTop() {
      return this.pageconfig.paddingTop === undefined ? 0 : this.pageconfig.paddingTop
    },
    _paddingBottom() {
      return this.pageconfig.paddingBottom === undefined ? 0 : this.px2rem(this.pageconfig.paddingBottom)
    },
    _footerHeight() {
      return this.px2rem(this.option.footerconfig.height || 0)
    },
    _headerHeight() {
      return this.px2rem(this.option.headerconfig.height || 0)
    },

    _components() {
      const _map = []
      const valuesIdMap = {}
      this.components.forEach(components => {
        components.forEach(com => {
          if (this.values[com.name] !== undefined) {
            valuesIdMap[com.id] = this.values[com.name]
          }
        })
      })
      this.components.forEach(components => {
        const t = []
        components.forEach(component => {
          const field = FieldMap.getField(component.type)
          const { target } = field
          t.push({
            type: target,
            id: component.id,
            option: component,
            values: this.values,
            valuesIdMap,
            key: randomString(8)
          })
        })
        _map.push(t)
      })
      return _map
    },
    linearGradBg() {
      const bg = this.pageconfig.isLinearGradBg ? 'linear-gradient(' + this.pageconfig.direction + ', ' + this.pageconfig.pageBgStartColor + ', ' + this.pageconfig.pageBgEndColor + ')' : (this.pageconfig.pagecolor || '#fff')
      return bg
    },
    _isFollow() {
      return this.pageconfig.isFollow
    }

  },
  created() {
    this.init()
  },
  methods: {
    handleScroll(e) {
      const h = e.target.scrollTop
      const px = this._header ? 88 - h : 0 - h
      if (this.pageimage && this._isFollow) {
        this.$refs.appMaker.style['background-position'] = px === 0 ? '0 0' : `0 ${this.px2rem(px)}`
      }
    },
    styleInfo() {
      if (this.pageconfig.isLinearGradBg) {
        return { 'background': this.linearGradBg }
      } else {
        const bg = { 'background-color': this.pagecolor, 'background-image': `url(${this.pageimage})` }
        bg['background-position'] = `0 ${this._header ? this.px2rem(88) : 0}`
        // bg['background-attachment'] = `scroll`
        if (this._paddingTop > 0) {
          this.$nextTick(() => {
            this.$refs.setTop.style['margin-top'] = ` ${this.px2rem(this._paddingTop)}`
          })
        }
        return bg
      }
    },
    ptFun() {
      console.log('padding==', `${this._header ? this.px2rem(this._paddingTop + 88) : this.px2rem(this._paddingTop)}`)
      return `${this._header ? this.px2rem(this._paddingTop + 88) : this.px2rem(this._paddingTop)}`
    },
    px2rem(px) {
      return px && (px / 75 * 1 + 'rem') || ''
    },
    close() {
      this.$modal.hideAll()
    },
    init() {
      this.queue = new Queue()
      this.map = this._components
      this.on_event('filed-value-change', (e) => {
        e.stopPropagation()
        this.change(e)
      })
      this.on_event('change', (e) => {
        e.stopPropagation()
        this.change(e)
      })
    },

    change(e) {
      const changeId = e.target.option.id
      const ths = this
      this.queue.add(() => {
        const { relation } = this
        return Object.keys(relation).reduce((a, targetId) => {
          return a.then(() => {
            const relates = (relation[targetId] || [])
            if (relates.length > 0) {
              let result = false
              let type = ''
              let relateMap = ''
              return relates.reduce((_a, a) => {
                return _a.then(() => {
                  const { id, operate, value, valueType, display } = a.relate
                  const target = this.getWidgetById(id)
                  if (id === changeId && target) {
                    relateMap = value
                    return Promise.resolve().then(() => {
                      const type = target.option.type
                      return Promise.resolve().then(() => target.getValue()).then(value => {
                        return {
                          lvalue: value,
                          lvalueType: FieldMap.getField(type).valueType
                        }
                      })
                    }).then(({ lvalue, lvalueType }) => {
                      return FieldMap.invokeOperate({
                        operate,
                        lvalue,
                        lvalueType,
                        rvalue: value,
                        rvalueType: valueType
                      })
                    }).then(r => {
                      result = r
                      type = display
                      ths.execute(result, type, targetId, changeId, relateMap)
                    })
                  }
                })
              }, Promise.resolve())
              //     Promise.resolve()).then(() => {
              //   console.log('result',result)
              //   console.log('type',type)
              //   console.log('targetId',targetId)
              //   if (result) {
              //     if (type == 1) {
              //       this.commit('unhide-some', targetId)
              //     } else if (type == 2) {
              //       this.commit('hide-some', targetId)
              //     } else if (type == 3) {
              //       this.commit('set-field-prop', { target: targetId, prop: 'disabled', value: true })
              //     } else if (type == 4) {
              //       this.commit('set-field-prop', { target: targetId, prop: 'required', value: true })
              //     } else if (type == 5) {
              //       this.commit('set-field-prop', { target: targetId, prop: 'required', value: false })
              //     } else if (type == 6) {
              //       this.commit('set-field-prop', { target: targetId, prop: 'disabled', value: false })
              //     } else if (type == 7) {
              //       this.commit('field-refresh', targetId, changeId, relateMap)
              //     } else if (type == 71) {
              //       this.commit('field-extend1', targetId, changeId, relateMap)
              //     } else if (type == 72) {
              //       this.commit('field-extend2', targetId, changeId, relateMap)
              //     } else if (type == 73) {
              //       this.commit('field-extend3', targetId, changeId, relateMap)
              //     } else if (type == 74) {
              //       this.commit('field-extend4', targetId, changeId, relateMap)
              //     } else if (type == 75) {
              //       this.commit('field-extend5', targetId, changeId, relateMap)
              //     } else if (type == 8) {
              //       this.commit('field-unhide-and-refresh', targetId, changeId, relateMap)
              //     }
              //   } else {
              //     if (type == 1) {
              //       this.commit('hide-some', targetId)
              //     } else if (type == 2) {
              //       this.commit('unhide-some', targetId)
              //     } else if (type == 3) {
              //       this.commit('set-field-prop', { target: targetId, prop: 'disabled', value: false })
              //     } else if (type == 4) {
              //       this.commit('set-field-prop', { target: targetId, prop: 'required', value: false })
              //     } else if (type == 5) {
              //       this.commit('set-field-prop', { target: targetId, prop: 'required', value: true })
              //     } else if (type == 6) {
              //       this.commit('set-field-prop', { target: targetId, prop: 'disabled', value: true })
              //     }else if (type == 8) {
              //       this.commit('field-unhide-and-refresh', targetId, changeId, relateMap)
              //     }
              //   }
              // })
            }
          })
        }, Promise.resolve())
      })
    },

    execute(result, type, targetId, changeId, relateMap) {
      if (result) {
        if (type == 1) {
          this.commit('unhide-some', targetId)
        } else if (type == 2) {
          this.commit('hide-some', targetId)
        } else if (type == 3) {
          this.commit('set-field-prop', { target: targetId, prop: 'disabled', value: true })
        } else if (type == 4) {
          this.commit('set-field-prop', { target: targetId, prop: 'required', value: true })
        } else if (type == 5) {
          this.commit('set-field-prop', { target: targetId, prop: 'required', value: false })
        } else if (type == 6) {
          this.commit('set-field-prop', { target: targetId, prop: 'disabled', value: false })
        } else if (type == 7) {
          this.commit('field-refresh', targetId, changeId, relateMap)
        } else if (type == 71) {
          this.commit('field-extend1', targetId, changeId, relateMap)
        } else if (type == 72) {
          this.commit('field-extend2', targetId, changeId, relateMap)
        } else if (type == 73) {
          this.commit('field-extend3', targetId, changeId, relateMap)
        } else if (type == 74) {
          this.commit('field-extend4', targetId, changeId, relateMap)
        } else if (type == 75) {
          this.commit('field-extend5', targetId, changeId, relateMap)
        } else if (type == 8) {
          this.commit('field-unhide-and-refresh', targetId, changeId, relateMap)
        }
      } else {
        if (type == 1) {
          this.commit('hide-some', targetId)
        } else if (type == 2) {
          this.commit('unhide-some', targetId)
        } else if (type == 3) {
          this.commit('set-field-prop', { target: targetId, prop: 'disabled', value: false })
        } else if (type == 4) {
          this.commit('set-field-prop', { target: targetId, prop: 'required', value: false })
        } else if (type == 5) {
          this.commit('set-field-prop', { target: targetId, prop: 'required', value: true })
        } else if (type == 6) {
          this.commit('set-field-prop', { target: targetId, prop: 'disabled', value: true })
        } else if (type == 8) {
          this.commit('field-unhide-and-refresh', targetId, changeId, relateMap)
        }
      }
    },

    commit(type, data, relateId, relateMap) {
      switch (type) {
        case 'hide-some':
          this.hideSome(data)
          break
        case 'unhide-some':
          this.unhideSome(data)
          break
        case 'set-field-prop':
          this.setFieldProp(data)
          break
        case 'field-refresh':
          this.setFieldRefresh(data, relateId, relateMap)
          break
        case 'field-extend1':
          this.setFieldExtend(1, data, relateId, relateMap)
          break
        case 'field-extend2':
          this.setFieldExtend(2, data, relateId, relateMap)
          break
        case 'field-extend3':
          this.setFieldExtend(3, data, relateId, relateMap)
          break
        case 'field-extend4':
          this.setFieldExtend(4, data, relateId, relateMap)
          break
        case 'field-extend5':
          this.setFieldExtend(5, data, relateId, relateMap)
          break
        case 'field-unhide-and-refresh': // 显示并刷新
          this.unhideSome(data)
          this.setFieldRefresh(data, relateId, relateMap)
          break
      }
    },

    hideSome(id) {
      // debugger
      if (!this.hideList.includes(id)) {
        this.hideList.push(id)
      }
    },

    unhideSome(id) {
      const index = this.hideList.indexOf(id)
      if (index !== -1) {
        this.hideList.splice(index, 1)
      }
    },

    setFieldProp({ target, prop, value }) {
      this.map.some(a => {
        const f = (a || []).find(b => b.id === target)
        if (f) {
          f.option[prop] = value
          return true
        }
      })
    },

    setFieldRefresh(id, relateId, relateMap) {
      this.getWidgetById(id).refresh(this.getWidgetById(relateId), relateMap)
    },
    setFieldExtend(t, id, relateId, relateMap) {
      switch (t) {
        case 1:
          this.getWidgetById(id).extend1(this.getWidgetById(relateId), relateMap)
          break
        case 2:
          this.getWidgetById(id).extend2(this.getWidgetById(relateId), relateMap)
          break
        case 3:
          this.getWidgetById(id).extend3(this.getWidgetById(relateId), relateMap)
          break
        case 4:
          this.getWidgetById(id).extend4(this.getWidgetById(relateId), relateMap)
          break
        case 5:
          this.getWidgetById(id).extend5(this.getWidgetById(relateId), relateMap)
          break
      }
    },

    getWidgets() {
      return this.$refs.widget.filter(a => a.option && a.option.mold == 'field')
    },

    getWidgetById(id) {
      return this.$refs.widget.find(a => a.option && a.option.mold == 'field' && a.option.id == id)
    }
  }
}
</script>
<style lang="scss" scoped>
@import '@/styles/var.scss';
@import '@/styles/utility/position.scss';
@import '@/styles/utility/shadow.scss';
@import '@/styles/utility/center.scss';
@import '@/styles/utility/rem.scss';

.apps-maker {
  position: relative;
  box-sizing: border-box;
  width: 375px;
  margin: 0 auto;
  height: 88vh;
  background-color: $f9;
  background-repeat: no-repeat !important;
  background-size: 100%;
  border-radius: rem(30);
  @include boxShadow(3);

  overflow-x: hidden;

  &::-webkit-scrollbar {
    display: none;
  }

  .apps-maker-body-banner {
    position: sticky;
    top: 0;
    width: 375px;
    height: 64px;
    margin: 0 auto;
    background-color: #fff;
    border-radius: 0 0;
    box-shadow: #ebedf0 0 4px 12px;
    z-index: 999;

    > div {
      border-radius: 0 0;
      background: url("../../images/pageditor/header.png") no-repeat 50% /
            cover;
      font-size: 14px;
      display: block;
      height: 64px;
      line-height: 82px;
      text-overflow: ellipsis;
      white-space: nowrap;
      overflow: hidden;
      margin: 0 auto;
      position: relative;

      .close-banner {
        position: absolute;
        left: 13px;
        bottom: 10px;
        width: 20px;
        height: 20px;
        cursor: pointer;
      }
    }
  }

  &-header {
    position: sticky;
    top: 0px;
    //position: absolute;
    //top: 0;
    //left: 0;
    //right: 0;
    z-index: 9;
    box-sizing: border-box;
  }

  &-body {
    min-height: 88vh;
    position: relative;

    .widget-item {
      position: relative;

      &.hide {
        display: none;
      }
    }
  }

  &-footer {
    position: sticky;
    bottom: 0;
    box-sizing: border-box;
  }

  &.is-footer {
    .apps-maker-body {
      padding-bottom: rem(128);
    }
  }
}
</style>
